<template>
  <div class="digital-cockpit">
    <!-- 顶部导航 -->
    <van-nav-bar class="nav-bar">
      <template #title>
        <span class="nav-title">数字分身</span>
      </template>
      <template #left>
        <van-icon name="wap-nav"  style="color: #26B1A1" @click="toggleLeftPanel"/>
      </template>
    </van-nav-bar>

    <!-- 左侧弹出面板 -->
    <van-popup
        v-model="showLeftPanel"
        position="left"
        :overlay="true"
        :style="{ width: '280px', height: '100%' }"
        get-container="body"
    >
      <div class="left-panel">
        <div class="panel-controls">
          <van-button
              class="collapse-btn"
              type="default"
              @click="toggleLeftPanel"
              icon="cross"
          />
        </div>
        <div class="conversation-header">
          <h3 style="color:#26B1A1;">对话历史</h3>
          <button class="new-convo-btn" @click="createNewConversation">
            <van-icon name="add-o"></van-icon><span>创建新对话</span>
          </button>
        </div>
        <div class="conversation-list">
              <div class="time-group" v-if="getTodayConversations().length > 0">
            <div class="time-group-title">今天</div>
            <div
                v-for="conversation in getTodayConversations()"
                :key="conversation.id"
                :class="['conversation-item', { active: activeConversation === conversation.id }]"
                @click="switchConversation(conversation.id)"
            >
              <div class="conversation-content">
                <div class="conversation-title">{{ conversation.name}}</div>
                <div class="conversation-preview">
                  <span class="timestamp">{{ showtime(conversation.time) }}</span>
                </div>
              </div>
              <button class="delete-btn" @click="deleteConversation(conversation.id, $event)">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                  <path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
              </button>
            </div>
          </div>
              <!-- 昨天 -->
              <div class="time-group" v-if="getYesterdayConversations().length > 0">
            <div class="time-group-title">昨天</div>
            <div
                v-for="conversation in getYesterdayConversations()"
                :key="conversation.id"
                :class="['conversation-item', { active: activeConversation === conversation.id }]"
                @click="switchConversation(conversation.id)"
            >
              <div class="conversation-content">
                <div class="conversation-title">{{ conversation.name}}</div>
                <div class="conversation-preview">
                  <span class="timestamp">{{ showtime(conversation.time) }}</span>
                </div>
              </div>
              <button class="delete-btn" @click="deleteConversation(conversation.id, $event)">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                  <path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
              </button>
            </div>
          </div>
            <!-- 近7日 -->
              <div class="time-group" v-if="getLast7DaysConversations().length > 0">
            <div class="time-group-title">近7日</div>
            <div
                v-for="conversation in getLast7DaysConversations()"
                :key="conversation.id"
                :class="['conversation-item', { active: activeConversation === conversation.id }]"
                @click="switchConversation(conversation.id)"
            >
              <div class="conversation-content">
                <div class="conversation-title">{{ conversation.name}}</div>
                <div class="conversation-preview">
                  <span class="timestamp">{{ showtime(conversation.time) }}</span>
                </div>
              </div>
              <button class="delete-btn" @click="deleteConversation(conversation.id, $event)">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                  <path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
              </button>
            </div>
          </div>
            <!-- 更多 -->
              <div class="time-group" v-if="getOlderConversations().length > 0">
            <div class="time-group-title">更多</div>
            <div
                v-for="conversation in getOlderConversations()"
                :key="conversation.id"
                :class="['conversation-item', { active: activeConversation === conversation.id }]"
                @click="switchConversation(conversation.id)"
            >
              <div class="conversation-content">
                <div class="conversation-title">{{ conversation.name}}</div>
                <div class="conversation-preview">
                  <span class="timestamp">{{ showtime(conversation.time) }}</span>
                </div>
              </div>
              <button class="delete-btn" @click="deleteConversation(conversation.id, $event)">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                  <path d="M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>
    </van-popup>


    <div class="chat-container" v-if="activeTab==2">
      <div v-if="isSwitching" class="loading-overlay" >
        <van-loading size="24px" type="spinner" vertical><span style="color: #26B1A1">加载中...</span></van-loading>
      </div>

      <div class="messages" ref="messagesContainer" :class="{ 'empty-messages': messages.length === 0 }">
        <!-- 原有消息列表 -->
        <div v-if="messages.length === 0" class="empty-state">
          <img src="@/assets/initnone.png" width="100%" style="position: relative;bottom: 14vh;"/>
        </div>
        <div
            v-for="(message, index) in messages"
            :key="index"
            :class="['message', message.role]"
            @touchstart="startPress(message)"
            @touchend="endPress"
        >
          <img
              v-if="message.role === 'assistant'"
              src="@/assets/logoz.png"
              alt="助手头像"
              class="avatar"
          >
          <div v-if="message.contextType === 'image'" class="image-content">
            <van-image
                fit="cover"
                :src="getFullImagePath(message.content)"
                @click="previewImage(message.content)"
            />
          </div>
          <div
              v-else-if="message.contextType === 'file'"
              class="file-content"
              @click="downloadFile(message)">
            <div class="file-info">
              <div class="file-name">{{ message.content }}</div>
              <div class="file-size">{{ formatFileSize(message.fileSize) }}</div>
            </div>
            <div class="file-icon">
              <van-icon
                  name="link-o"
                  size="24px"/>
            </div>
          </div>

          <div class="message-content" v-else>
            <!-- 显示引用消息 -->
            <div v-if="message.quotedMessage" class="quoted-message">
              <div class="quoted-label">引用:</div>
              <div class="quoted-content">
<!--              {{ message.quotedMessage.content.substring(0, 78) }}{{ message.quotedMessage.content.length > 78 ? '...' : '' }}-->
                {{ message.quotedMessage.content.replace(/<[^>]*>/g, '').substring(0, 30) }}{{ message.quotedMessage.content.replace(/<[^>]*>/g, '').length > 30 ? '...' : '' }}
              </div>
            </div>
            <!-- 显示消息内容 -->
            <div v-html="message.content"></div>
            <!-- 复制按钮 -->
            <div class="copy-btn" @click="copyCode($event)">
              <van-icon name="copy" size="16" color="#fff" />
            </div>
          </div>

<!--            <div class="message-content" v-else v-html="message.content">-->
<!--              <div class="copy-btn" @click="copyCode($event)">-->
<!--                <van-icon name="copy" size="16" color="#fff" />-->
<!--              </div>-->
<!--            </div>-->
        </div>
      </div>


      <!-- 记忆功能开关 -->
      <div class="memory-switch">
        <span class="cancel-sub"></span>
        <span>记忆功能:</span>
        <van-switch
            v-model="memoryEnabled"
            @change="handleMemorySwitchChange"
            size="small"
        />
        <van-button size="small" class="btn-executor" icon="label-o" @click="updateSubscriptionPanel">订阅管理</van-button>
      </div>

      <van-action-sheet
          v-model="showActionSheet"
          :actions="actions"
          cancel-text="取消"
          @select="onActionSelect"
          @cancel="onActionCancel"
      />

      <div class="quote-panel" v-if="showQuotePanel && quotedMessage">
        <div class="quote-content">
          <div class="quote-header">
            <span>引用消息</span>
            <van-icon name="cross" @click="cancelQuote" />
          </div>
          <div class="quote-message">
            {{ quotedMessage.content.replace(/<[^>]*>/g, '').substring(0, 30) }}{{ quotedMessage.content.replace(/<[^>]*>/g, '').length > 30 ? '...' : '' }}
          </div>
        </div>
      </div>
      <div class="input-footer">
        <form @submit.prevent="handleSubmit" class="input-form">
          <div class="input-container">
            <input
                type="text"
                v-model="input"
                :disabled="isLoading"
                placeholder="请输入问题"
                class="input-box"
            >
            <button
                type="submit"
                :disabled="isLoading || !input.trim()"
                class="send-btn"
            >
              <img
                  src="@/assets/fasong2.png"
                  alt="发送"
                  class="send-icon"
                  :class="{ 'send-icon-disabled': isLoading || !input.trim() }"
              >
            </button>
          </div>
        </form>
      </div>
    </div>

    <van-image-preview
        v-model="showImagePreview"
        :images="previewImages"/>
  </div>
</template>

<script>
import { marked } from 'marked';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css'; // 代码高亮样式
import 'github-markdown-css/github-markdown.css'; // GitHub Markdown 基础样式
import { getAction,postAction } from '@/api'
import mqHandler from '../chat/util/mqHandler'
import Vue from "vue";
export default {
  components:{marked},
  data() {
    return {
      showLeftPanel: false,
      activeTab: 2,
      messages: [
        // {
        //   role: 'assistant',
        //   content: '我是数字分身，您的个人AI助手。请问有什么可以帮助您的？'
        // }
      ],
      input: '',
      isLoading: false,
      memoryEnabled: false,
      conversationMap: {},
      psn_code:'',
      enterFlag:true,
      toContactId:'', //对应机器人id
      toContactkey: '', //对应机器人key
      conversations: [],// 所有对话列表
      activeConversation: null,  // 当前活动对话ID
      newConversationId: 1,      // 用于生成新对话ID
      isSwitching:false,
      showImagePreview: false,
      previewImages: [],
      quotedMessage: null, // 被引用的消息
      showQuotePanel: false, // 是否显示引用面板
      pressTimer: null, // 长按计时器
      longPressDetected: false, // 是否检测到长按
      showActionSheet: false,
      actions: [
        // { name: '复制', value: 'copy' },
        { name: '引用', value: 'quote' }
      ],
      selectedMessage: null,
    };
  },
  created() {
    // if(!this.$store.getters.mqClient){
    //   console.log("创建mq连接:")
    //   mqHandler.connect();
    // }
    console.log("监听新消息:",Vue.prototype.$bus.$on('message', this.handleNewMessage))
    this.initMessageList()
    marked.setOptions({
      highlight: (code, lang) => {
        // 代码高亮逻辑（仅执行一次初始化）
        if (lang && hljs.getLanguage(lang)) {
          return hljs.highlight(code, { language: lang }).value;
        }
        return hljs.highlightAuto(code).value;
      },
      gfm: true, // 支持表格、任务列表等 GitHub 语法
      breaks: true, // 支持换行符
      tables: true
    });
  },
  beforeDestroy(){
    Vue.prototype.$bus.$off('message', this.handleNewMessage);
  },
  mounted() {
    if(this.$route.params.activeTab){
      this.activeTab=this.$route.params.activeTab
    }
    this.getPsnCode()

  },
  methods: {
    startPress(message) {
      // 如果是图片或文件，不触发长按菜单
      if (message.contextType === 'image' || message.contextType === 'file') {
        return;
      }
      this.longPressDetected = false;
      this.pressTimer = setTimeout(() => {
        this.longPressDetected = true;
        this.selectedMessage = message;
        this.showActionSheet = true;
      }, 600);
    },
    endPress() {
      clearTimeout(this.pressTimer);
    },
    onActionSelect(action) {
      if (action.value === 'copy') {
        this.copyToClipboard(this.selectedMessage.content);
        this.$toast.success('已复制');
      } else if (action.value === 'quote') {
        this.quotedMessage = this.selectedMessage;
        this.showQuotePanel = true;
      }
      this.showActionSheet = false;
    },

    onActionCancel() {
      this.selectedMessage = null;
    },

    copyToClipboard(text) {
      const textarea = document.createElement('textarea');
      textarea.value = text;
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand('copy');
      document.body.removeChild(textarea);
    },

    cancelQuote() {
      this.quotedMessage = null;
      this.showQuotePanel = false;
    },

    downloadFile(msg) {
      // var url = window._CONFIG['staticDomainURL'] + msg.content
      var url = 'http://localhost:9997/weipu-boot/sys/common/static/' + msg.content;
      fetch(url) //使用fetch函数发送一个GET请求到指定的URL，获取文件的响应对象。
          .then(response => response.blob()) //通过.then方法链，将响应对象转换为Blob数据（文件的二进制数据）。
          .then(blob => { //再次使用.then方法链，处理获取到的Blob数据。
            const link = document.createElement('a'); //使用document.createElement创建一个<a>节点。
            link.href = URL.createObjectURL(
                blob); //通过URL.createObjectURL方法，将Blob数据转换成URL对象，然后将该URL赋值给link的href属性。这一步相当于生成了一个临时URL，供下载使用。
            link.download = msg.content; // 替换为你要保存的文件名和扩展名(设置用户下载文件时使用的文件名和扩展名)
            link.click(); //调用click方法模拟用户点击链接，从而触发浏览器的文件下载行为。
            URL.revokeObjectURL(link.href); // 释放URL对象资源(使用URL.revokeObjectURL方法释放之前创建的URL对象资源，避免内存泄漏)
          })
          .catch(error => {
            console.error('下载失败:', error);
          });
      console.log('下载文件:', msg.content)
      this.$toast(`开始下载: ${msg.content}`)
    },
    formatFileSize(bytes) {
      if (bytes === 0) return '0 Bytes';
      const k = 1024;
      const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },
    getFullImagePath(avatar) {
      const path = avatar.startsWith('/') ? avatar : `/${avatar}`;
      return window._CONFIG['staticDomainURL'] + path;
    },
    previewImage(imageUrl) {
      this.previewImages = [ window._CONFIG['staticDomainURL']+'/'+imageUrl ]
      this.showImagePreview = true
    },
    toggleLeftPanel() {
      this.showLeftPanel = !this.showLeftPanel;
    },
    getTodayConversations() {
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      return this.conversations.filter(conv => {
        const convDate = new Date(conv.time);
        return convDate >= today;
      });
    },
    getYesterdayConversations() {
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      const yesterday = new Date(today);
      yesterday.setDate(yesterday.getDate() - 1);

      return this.conversations.filter(conv => {
        const convDate = new Date(conv.time);
        return convDate >= yesterday && convDate < today;
      });
    },
    getLast7DaysConversations() {
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      const sevenDaysAgo = new Date(today);
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

      return this.conversations.filter(conv => {
        const convDate = new Date(conv.time);
        return convDate >= sevenDaysAgo && convDate < today;
      }).filter(conv => {
        // 排除今天和昨天的对话
        const convDate = new Date(conv.time);
        const yesterday = new Date(today);
        yesterday.setDate(yesterday.getDate() - 1);
        return convDate < yesterday;
      });
    },
    getOlderConversations() {
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      const sevenDaysAgo = new Date(today);
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

      return this.conversations.filter(conv => {
        const convDate = new Date(conv.time);
        return convDate < sevenDaysAgo;
      });
    },
    // 创建新对话
    createNewConversation() {
      if (this.messages.length == 0) {
        this.$toast('您已经在一个新对话中')
      } else {
        this.isSwitching = true; // 开始加载
        postAction('/conversation/saveandupdate', {activeConversation: this.activeConversation}).then(res => {
          if (res.success) {
            try {
              this.$toast.success(res.result)
              this.getconversation()
            }finally {
              this.showLeftPanel=false,
              setTimeout(() => {
                this.isSwitching = false; // 结束加载
              }, 500); // 确保加载状态至少持续500毫秒，以防止闪烁
            }
          } else {
            this.$toast.fail('新对话创建失败，请稍后再试')
          }
        })
      }
    },
    // 切换对话
    switchConversation(conversationId) {
      this.isSwitching = true; // 开始加载
      //当前对话id变更
      postAction('/conversation/updateConversation', {activeConversation: conversationId}).then(res => {
        if(res.success){
          try {
            this.getconversation()
          }finally {
            this.showLeftPanel=false,
            setTimeout(() => {
              this.isSwitching = false; // 结束加载
            }, 500); // 确保加载状态至少持续500毫秒，以防止闪烁
          }
        }
      })
    },
    // 删除对话
    deleteConversation(conversationId) {
      event.stopPropagation(); // 阻止事件冒泡
      this.isSwitching = true; // 开始加载
      postAction('/conversation/removeConversation', {activeConversation: conversationId}).then(res => {
        if (res.message=='您已经在一个新对话中,无法删除') {
          this.$toast('您已经在一个新对话中,无法删除')
          this.isSwitching = false; // 结束加载
        }else {
          this.$toast.success('对话删除成功')
          this.showLeftPanel=false
          setTimeout(() => {
            this.getconversation()
            this.isSwitching = false; // 结束加载
          }, 500); // 确保加载状态至少持续500毫秒，以防止闪烁
        }
      })
    },
    showtime(time){
      return time.substring(0,19)
    },
    //处理未读数
    zeroUnread(toContactId, unread) {
      //减去消息未读总数
      unread = unread == 0 ? 1 : unread;
      console.log(unread)
      postAction("/sys/chat/relative/zeroUnread", {
        goalId: toContactId,
        myId: this.$store.getters.userid
      }).then(res => {
        console.log("🚀 ~ file: chat.vue:958 ~ zeroUnread ~ res:", res)
        mqHandler.send({
          channelid: '12138',
          type: 'OneToOneRead',
          sendid: this.$store.getters.userid,
          receiveid: toContactId,
          info: {},
          time: new Date().toLocaleString().replace(/\//g, '-'),
          timestamp: new Date().getTime()
        })
      })
    },
    //处理通报消息
    handleNewMessage(message){
      if (message.type =='OneToOne'){
        console.log("收到新消息", message)
      }
      this.messages.push({
        role: 'assistant',
        content: message.info.msgcontent
      });
      this.scrollToBottom()
      if (this.toContactId == message.sendid){
        this.zeroUnread(this.toContactId, 0)
      }
    },
    //初始化消息记录
    initMessageList() {
      postAction('/sys/chat/bot/getBot', {
        userId: this.$store.getters.userid
      }).then((res) => {
        this.toContactId = res.result[0].id
        this.toContactkey = res.result[0].key
        this.getconversation()
      })
    },
    getconversation(){
      //查询对话列表
      getAction('/conversation/list').then(res=>{
        //代表是第一次聊天没有聊天记录留存
        if(res.result==null){
          postAction('/conversation/save').then(res=>{
            this.conversations=[]
            //当前活动对话ID
            this.activeConversation=res.result
            //查询对话历史
            this.conversations.push({id:res.result,name:'新对话',time:new Date().toLocaleString()})
          })
        }else{
          //绑定历史列表
          this.conversations=res.result
          //查询当前得activeConversation
          for(let i=0;i<this.conversations.length;i++){
            if(this.conversations[i].currents=='true'){
              this.activeConversation=this.conversations[i].id
              break;
            }
          }
        }
        this.getChatlist()
      })
    },
    getChatlist(){
      // 跟据当前活动对话ID来查询消息列表
      postAction('/sys/chat/message/list2', {
        num: 0,
        size: -1,
        toContactId: this.toContactId,
        userId: this.$store.getters.userid,
        conversationId: this.activeConversation
      }).then((res) => {
        var _list = res.result;
        if (_list.length > 0) {
          this.messages = _list.map(item => {
            let quotedMessage = null;
            if (item.quotedMessage && item.quotedMessage !== 'null') {
              // 使用正则表达式提取 role 和 content
              const roleMatch = item.quotedMessage.match(/role=([^,]+)/);
              const contentMatch = item.quotedMessage.match(/content=([^}]+)/);

              if (roleMatch && contentMatch) {
                quotedMessage = {
                  role: roleMatch[1].trim(),
                  content: contentMatch[1].trim().replace(/}$/, '') // 去除可能存在的结尾大括号
                };
              }
            }

            return {
              role: item.senderId === this.toContactId ? 'assistant' : 'user',
              content: item.isAgent == 'true' ? this.updateMessageContent2(item) : item.message,
              isAgent: item.isAgent,
              contextType: item.contextType,
              fileSize: item.fileSize,
              quotedMessage: quotedMessage
            };
          });
        }else {
          this.messages = [];
        }
        if (this.enterFlag) {
          this.$nextTick(() => {
            this.scrollToBottom();
          });
          this.enterFlag = false 	// 初次加载消息列表时滑动到底部
        }
      }).catch((err) => {
        console.error('获取消息列表失败:', err)
      })
      this.zeroUnread(this.toContactId,0)
    },
    getPsnCode(){
      getAction('/sys/getPsnCode',{username:this.$store.getters.username}).then(res=>{
        this.psn_code=res
      })
    },
    formatTime() {
      const date = new Date()
      return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`
    },    //能力助手
    handleMemorySwitchChange(checked) {
      if (!checked) {
        // 关闭时清空所有记忆
        this.conversationMap = {};
        this.$toast('已清除所有对话记忆');
      }
    },
    formatTime2(timestamp = null) {
      // 如果传入时间戳，使用它；否则使用当前时间
      const date = timestamp ? new Date(timestamp) : new Date();

      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hours = String(date.getHours()).padStart(2, '0');
      const minutes = String(date.getMinutes()).padStart(2, '0');
      const seconds = String(date.getSeconds()).padStart(2, '0');

      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
    originalSendTextMessage(){
      //调用sendUser接口 存储发送的文字消息
      return new Promise((resolve, reject) => {
      const newMsg = {
        id: Date.now(),
        senderId: this.$store.getters.userid,
        type: 'text',
        message: this.input,
        sendTime: this.formatTime(),
        realname: this.$store.getters.nickname,
        avatar: this.$store.getters.avatar,
        fileName: null,
        fileSize: null
      }
      postAction('/sys/chat/message/sendUser', {
        message: newMsg.message, 	//消息内容
        senduserId: newMsg.senderId, 	//发起人id
        senduserRealname: newMsg.realname, 		//发起人名字
        senduserAvatar: newMsg.avatar,		 //发起人头像
        recipientid: this.toContactId, 		//接收人
        type: newMsg.type,		 //消息类型
        duration: 0,	 //语音时长
        isGroup: 0,	 //是否是群聊
        groupUserIds: [],	//群聊用户id（不包括自己）
        fileName: newMsg.fileName,
        fileSize: newMsg.fileSize,
        conversationId: this.activeConversation,
        quotedMessage: this.quotedMessage ? {...this.quotedMessage} : null
      }).then((res) => {
        if (!res.success) {
          this.$toast.fail('消息发送失败')
          reject('消息发送失败')
          return
        }
        resolve(res.result.sendTime)  // 成功时 resolve
        }).catch(err => {
          reject(err) // 捕获错误
        })
      })
    },

    async handleSubmit() {
      if (!this.input.trim() || this.isLoading) return;
      const userMessage = {
        role: 'user',
        content: this.input,
        quotedMessage: this.quotedMessage ? {...this.quotedMessage} : null};
      this.messages.push(userMessage);

      this.scrollToBottom();
      try {
        const userMsgTime = await this.originalSendTextMessage();
        const serverTimeStamp = new Date(userMsgTime).getTime();
        const delayedTimeStamp = serverTimeStamp + 1000;
        const robotMsgTime = this.formatTime2(delayedTimeStamp);

        const userInput = this.input;
        this.input = '';
        this.isLoading = true;

        const assistantMessage = {
          role: 'assistant',
          content: '',
          // quotedMessage: this.quotedMessage, // 添加引用消息
          rawContent: '',
          // contextType:'Quoted',
        };
        this.messages.push(assistantMessage);

        const activeConversation = JSON.parse(JSON.stringify(this.activeConversation));

        const quotedMessage = this.quotedMessage ? {...this.quotedMessage} : null;
        if (this.quotedMessage) {
          this.quotedMessage = null;
          this.showQuotePanel = false;
        }

        // 调用选择接口
        const param = {
          content: userInput,
          userid: this.$store.getters.userid
        };
        const res = await postAction('/chatapi/choice', param);

        if (res.code != 200) {
          this.$toast.fail(res.message);
          assistantMessage.content = '请求出错: ' + res.message;
        } else {
          var message = res.message.split('&&');
          if (message[0] != 'agent') {
            // 模拟流式输出返回的消息
            await this.simulateStreamingOutput(res.message, assistantMessage);
            // 保存数据
            postAction('/sys/chat/message/sendRobotText2?key='+this.toContactkey, {
              message: res.message,
              time: robotMsgTime,
              isAgent: true,
              mark: true,
              conversationId: activeConversation
            }).then(res => {
              if (res.result) {
                console.log('存储成功')
              }
            })
          } else {
            var api_id = message[1];
            // 如果是agent，显示提示信息
            assistantMessage.content = '加载中...';
            // 直接在前端调用智能体接口
            await this.callAgentApiDirectly(userInput, api_id, assistantMessage,robotMsgTime,quotedMessage,activeConversation);
          }
        }
      } catch (error) {
        console.error('Error:', error);
        this.messages[this.messages.length - 1].content = '抱歉，出错了: ' + error.message;
      } finally {
        this.isLoading = false;
        this.messages = [...this.messages];
        this.scrollToBottom();
      }
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.messagesContainer;
        container.scrollTop = container.scrollHeight;
      });
    },
    async callAgentApiDirectly(query, api_id, messageObj,time,quotedMessage,activeConversation) {
      var info = `<userinfo>当前用户：${this.$store.getters.username}，当前用户姓名：${this.$store.getters.nickname}，当前用户手机号：${this.$store.getters.phone}，当前用户MSSID（工号）：${this.psn_code}</userinfo>`;
      try {
        let requestBody= ''
        if(quotedMessage==null){
          // 构建请求体，根据记忆功能决定是否携带conversation_id
          requestBody = {
            inputs: {},
            query: `${info}\n${query}`,
            response_mode: "streaming",
            conversation_id: this.memoryEnabled ? this.conversationMap[api_id] || "" : "",
            user: this.$store.getters.userid
          };
        }else{
          // 构建请求体，根据记忆功能决定是否携带conversation_id
          requestBody = {
            inputs: {},
            query: `${info}\n${quotedMessage.content}\n${query}`,
            response_mode: "streaming",
            conversation_id: this.memoryEnabled ? this.conversationMap[api_id] || "" : "",
            user: this.$store.getters.userid
          };
        }


        const response = await fetch("/v1/chat-messages", {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${api_id}`
          },
          body: JSON.stringify(requestBody)
        });

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        const reader = response.body.getReader();
        const decoder = new TextDecoder('utf-8');
        let buffer = '';
        let fullResponse = '';
        messageObj.content = '';

        // eslint-disable-next-line no-constant-condition
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;

          buffer += decoder.decode(value, { stream: true });

          const lines = buffer.split(/\r\n|\r|\n/);
          buffer = lines.pop();

          for (const line of lines) {
            if (line.startsWith('data: ')) {
              const jsonStr = line.substring(6).trim();
              if (jsonStr === '') continue;

              try {
                const data = JSON.parse(jsonStr);

                // 存储conversation_id
                if (data.conversation_id && this.memoryEnabled) {
                  this.conversationMap[api_id] = data.conversation_id;
                }

                if ((data.event === 'agent_message' || data.event === 'message') && data.answer) {
                  const decodedAnswer = data.answer.replace(/\\u([\d\w]{4})/gi,
                      (match, grp) => String.fromCharCode(parseInt(grp, 16)));

                  fullResponse += decodedAnswer;
                  await this.streamOutput(fullResponse, messageObj);
                }
              } catch (e) {
                console.error('解析JSON出错:', e, '原始数据:', jsonStr);
              }
            }
          }
        }
        if(fullResponse!='') {
          postAction('/sys/chat/message/sendRobotText2?key='+this.toContactkey, {
            message: fullResponse,
            time: time,
            isAgent: true,
            mark: true,
            conversationId: activeConversation
          }).then(res => {
            if (res.result) {
              console.log('存储成功')
            }
          })
        }
      } catch (error) {
        console.error('调用智能体API出错:', error);
        messageObj.content = '调用智能体服务失败: ' + error.message;
        this.messages = [...this.messages];
        this.scrollToBottom();
        throw error;
      }
    },
    updateMessageContent2(messageObj) {
      // 如果直接输出，可能没有 rawContent，所以使用 message 作为源
      // 确保有内容需要处理
      if (messageObj.message && !messageObj.rawContent) {
        messageObj.rawContent = messageObj.message;
      }
      this.updateMessageContent(messageObj);
      return messageObj.message;
    },
    updateMessageContent(messageObj) {
      // 确保rawContent存在
      if (!messageObj.rawContent) {
        messageObj.rawContent = '';
      }

      // 统一转换处理
      messageObj.message = marked.parse(this.convertToMarkdown(messageObj.rawContent));
      this.messages = [...this.messages];
      this.scrollToBottom();
    },
    async streamOutput(fullText, messageObj) {
      // 计算需要新增的字符
      const currentLength = messageObj.rawContent ? messageObj.rawContent.length : 0;
      const newText = fullText.substring(currentLength);

      // 初始化rawContent如果不存在
      if (!messageObj.rawContent) {
        messageObj.rawContent = '';
      }
      // 逐字添加到原始内容
      for (let i = 0; i < newText.length; i++) {
        messageObj.rawContent += newText[i];

        // 解析为Markdown
        messageObj.content = marked.parse(this.convertToMarkdown(messageObj.rawContent));

        this.messages = [...this.messages];
        this.scrollToBottom();
        await new Promise(resolve => setTimeout(resolve, 30)); // 控制输出速度
      }
    },
    convertToMarkdown(input) {
      // 替换HTML实体
      let markdown = input
          .replace(/&gt;/g, '>')
          .replace(/&lt;/g, '<')
          .replace(/&quot;/g, '"')
          .replace(/<strong>name<\/strong>/g, '__name__')
          .replace(/<strong>main<\/strong>/g, '__main__');

      // 尝试识别代码块
      if (markdown.includes('def ') || markdown.includes('print(')) {
        // 确保代码块被正确包裹
        if (!markdown.startsWith('```python')) {
          markdown = "```python\n" + markdown.replace(/<\/?code>/g, '') + "\n```";
        }
      }

      // 移除残留的HTML标签
      markdown = markdown.replace(/<\/?p>/g, '');

      return markdown;
    },
// 模拟流式输出的方法（支持Markdown）
    async simulateStreamingOutput(text, messageObj) {
      // 初始化rawContent
      messageObj.rawContent = '';

      const characters = text.split('');
      for (let i = 0; i < characters.length; i++) {
        await new Promise(resolve => setTimeout(resolve, 50));
        messageObj.rawContent += characters[i];

        // 解析为Markdown
        messageObj.content = marked.parse(this.convertToMarkdown(messageObj.rawContent));

        this.messages = [...this.messages];
        this.scrollToBottom();
      }
    },
    copyCode(event) {
      // 找到当前点击的复制图标所在的代码块（pre标签）
      const pre = event.target.closest('pre');
      if (!pre) return;
      // 找到代码块中的代码内容（code标签）
      const code = pre.querySelector('code');
      if (!code) return;
      // 使用浏览器API复制文本
      navigator.clipboard.writeText(code.textContent)
          .then(() => {
            this.$toast.success('复制成功'); // 提示复制成功（使用vant的toast组件）
          })
          .catch(err => {
            this.$toast.fail('复制失败'); // 提示复制失败
            console.error('复制失败:', err);
          });
    },
    updateSubscriptionPanel(){
      this.$router.push({name: 'subscription',params:{mark:'能力助手'}})
    },
  }
};
</script>

<style scoped>
.quoted-message {
  background-color: #f0f6ff;
  border-left: 3px solid #1989fa;
  padding: 8px 12px;
  margin-bottom: 8px;
  border-radius: 4px;
  font-size: 0.9em;
}
.quoted-label {
  font-weight: bold;
  color: #1989fa;
  margin-bottom: 4px;
  font-size: 0.85em;
}
.quoted-content {
  color: #666;
  line-height: 1.4;
}

/* 引用消息面板样式 */
.quote-panel {
  background-color: #f5f5f5;
  padding: 8px 12px;
  border-top: 1px solid #eaeaea;
}
.quote-content {
  position: relative;
  padding: 8px;
  background-color: #fff;
  border-radius: 4px;
  border-left: 3px solid #26B1A1;
}
.quote-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #26B1A1;
  font-size: 12px;
  margin-bottom: 4px;
}
.quote-message {
  font-size: 14px;
  color: #666;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 消息中显示引用 */
.message .quoted-message {
  background-color: #f0f0f0;
  padding: 8px;
  border-radius: 4px;
  margin-bottom: 8px;
  font-size: 12px;
  color: #666;
  border-left: 2px solid #26B1A1;
}
.file-content {
  display: flex;
  align-items: center;
  padding: 8px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 8px;

  max-width: calc(100% - 50px); /* 40px头像 + 10px间距 */
  background-color: #fff;
  -webkit-box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
  color: #333;
  border-top-right-radius: 11px;
  border-top-left-radius: 11px;
  border-bottom-left-radius: 11px;
  position: relative;
  padding: 8px 12px;
  /*border-radius: 16px;*/
  font-size: 14px;
  line-height: 1.5;
  word-wrap: break-word;
  max-width: 100%;
}
.file-icon {
  margin-right: 10px;
  color: inherit;
}
.file-info {
  display: flex;
  flex-direction: column;
}
.file-name {
  font-weight: 500;
  font-size: 14px;
  word-wrap: break-word; /* 允许长单词换行 */
  white-space: pre-wrap; /* 保留空格并允许换行 */
  word-break: break-word; /* 优先单词换行，必要时截断 */
  max-width: 150px; /* 保留最大宽度限制 */
}
.file-size {
  font-size: 12px;
  opacity: 0.8;
}
/* 图片消息样式 */
.image-content {
  border-radius: 8px;
  overflow: hidden;
  max-width: 100px;
}
/deep/ .van-loading__spinner--spinner{
  color: #26B1A1;
}
.message-content {
  text-align: left;
  white-space: pre-line;
  white-space: pre-wrap;
}
/deep/ .van-tag--primary.van-tag--plain{
  background: #f2fffd;
  color: #26B1A1;
}
.nav-title {
  font-size: 16px;
  font-weight: bold;
  color: #26B1A1;
  letter-spacing: 0.5px;
}
.copy-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  cursor: pointer;
  opacity: 0.7; /* 初始半透明 */
  transition: opacity 0.3s; /*  hover 动画 */
}
.copy-btn:hover {
  opacity: 1; /* hover 时完全显示 */
}
/deep/ .van-overlay{
  background-color: rgb(0 0 0 / 15%) !important;
}
/deep/.van-switch{
  font-size: 16px !important;
}
.digital-cockpit {
  /*background-color: #f7f8fa;*/
  /*background-color: #fbfbfb;*/
  background: linear-gradient(180deg, #F4FCFE, #fff);
  min-height: 100vh;
}
/* 导航栏样式 */
.nav-bar {
  background-color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
/* 标签栏样式 */
.tab-bar {
  background-color: #fff;
  margin-bottom: 14px;
}
.tab-title {
  font-size: 16px;
  font-weight: 500;
}
/deep/.van-tabs__line {
  background-color: #27C2AD !important;
}
/deep/.van-tab--active{
  color: #27C2AD !important;
}
/* 搜索框样式 */
.search-box {
  padding: 0 16px 12px;
}
.search-input {
  background-color: white !important;
  border-radius: 5px;
  padding: 5px 0px !important;
}
.van-search__content{
  background-color: white !important;
}
/* 数字人列表样式 */
.digital-list {
  margin-bottom: 8vh;
  padding: 0 16px;
}
.digital-item {
  background-color: #fff;
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
/* 数字人标题区域 */
.digital-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.header-left {
  display: flex;
  align-items: center;
}
.avatar {
  width: 26px;
  height: 26px;
  margin-right: 12px;
}
.title-info {
  min-width: 0;
}
/deep/.van-divider{
  margin: 0px 0px 6px 0px;
}
.digital-title {
  font-size: 16px;
  font-weight: 500;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.digital-desc {
  padding-bottom: 8px;
  font-size: 14px;
  color: #c0c4c8;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.header-right {
  display: flex;
  align-items: center;
}
.switch-text {
  position: relative;
  margin-left: 8px;
  font-size: 13px;
  color: #666;
  bottom: 2px;
  right: 8px;
}
/* 信息卡片样式 */
.info-card {
  width: 100%;
  border: 1px solid #e5e6eb;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 6px;
}
.info-row {
  display: flex;
  width: 100%;
}
.header-row {
  background-color: #f4f8f9;
  color: #909399;
  font-size: 13px;
  border-bottom: 1px solid #e5e6eb;
}
.content-row {
  margin-top: -20px;
  background-color: #f5f7fa;
  color: #303133;
  font-size: 14px;
}
.info-col {
  flex: 1;
  padding: 12px 0;
  text-align: center;
  position: relative;
}
.info-col:not(:last-child)::after {
  content: '';
  position: absolute;
  right: 0;
  top: 15%;
  height: 70%;
  width: 1px;
  background-color: #e5e6eb;
}
/* 操作按钮样式 */
.action-buttons {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.cancel-sub {
  color: #f53f3f;
  font-size: 14px;
  cursor: pointer;
  padding: 4px;
}
.right-buttons {
  display: flex;
  gap: 8px;
}
.btn-pause {
  background-color: #f53f3f;
  color: #fff;
  border-radius: 32px;
}
.btn-executor {
  background-color: #27C2AD !important;
  color: #fff;
  border-radius: 8px;
  margin: 4px;
}
.btn-more {
  background-color: #e8f3ff;
  color: #1989fa;
  border-radius: 32px;
}
/* 适配小屏幕 */
@media (max-width: 375px) {
  .info-cell {
    flex: 0 0 50%;
  }

  .info-cell:nth-child(2)::after {
    display: none;
  }

  .info-cell:nth-child(3)::after {
    display: block;
  }
}
::v-deep .van-nav-bar__content{
  background: #F4FCFF;
}
/* 能力助手 */
.chat-container {
  height: 90vh; /* 占满屏幕高度 */
  display: flex;
  flex-direction: column;
  /*background-color: #f7f8fa;*/
  /*background-color: #fff;*/
  background: linear-gradient(180deg, #F4FCFE, #fff);
  overflow: hidden;
}
/* 消息列表：可滚动， flex占满剩余空间 */
.messages {
  flex: 1;
  padding: 20px 15px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
/* 滚动条美化（仅WebKit内核） */
&::-webkit-scrollbar {
   width: 6px;
 }
&::-webkit-scrollbar-thumb {
   background-color: #ddd;
   border-radius: 3px;
 }
}
.message {
  display: flex;
  align-items: center;

}
.avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  margin-right: 8px;
}
.message-content {
  font-size: 14px;
  padding: 8px 12px;
  border-radius: 4px;
  max-width: 100%;
  word-wrap: break-word;
  line-height: 1.8;
}
.message.user .message-content {
  max-width: calc(93% - 50px) !important; /* 右边预留20px间距 */
  background-color: #e8f3ff;
  color: black;
  padding: 10px 15px;
  margin-left: auto; /* 右对齐 */
  border-bottom-left-radius: 11px;
  border-top-right-radius: 11px;
  border-top-left-radius: 11px;
}
.message.assistant .message-content {
  max-width: calc(93% - 50px) !important;  /* 40px头像 + 10px间距 */
  background-color: #fff;
  -webkit-box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
  color: #333;
  border-top-right-radius: 11px;
  border-top-left-radius: 11px;
  border-bottom-right-radius: 11px;
  position: relative;
  padding: 8px 12px;
  /*border-radius: 16px;*/
  font-size: 14px;
  line-height: 1.5;
  word-wrap: break-word;
  max-width: 100%;
  /*padding: 10px 10px; !* 增加内边距，让内容更清晰 *!*/
}
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-right: 10px;
  object-fit: cover; /* 避免图片拉伸 */
}
.input-footer {
  margin-bottom: 10px;
  padding: 9px;
  background-color: #fff;
  border-top: 1px solid #eee;
}
.input-form {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 6px;
}
.input-container {
  position: relative;
  display: inline-block;
  width: 100%;
}
.input-box {
  flex: 1;
  padding: 12px 20px;
  border: 2px solid #26B1A1;
  border-radius: 8px;
  outline: none;
  font-size: 14px;
  transition: border-color 0.3s;
&:focus {
   border-color: #07c160; /* 聚焦时边框变品牌色 */
 }

&:disabled {
   background-color: #f5f5f5;
   cursor: not-allowed;
 }
}

 /*发送按钮：无背景，图标垂直居中*/
.send-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
.input-box {
  width: 100%;
  padding-right: 40px; /* 为按钮留出空间 */
  box-sizing: border-box;
}
.send-btn {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
/* 发送图标：大小调整，禁用时灰化 */
.send-icon {
  width: 28px;
  height: 28px;
  vertical-align: middle;
  transition: opacity 0.3s;
}
.send-icon-disabled {
  opacity: 0.5; /* 禁用时图标半透明 */
  cursor: not-allowed;
}
/* 记忆功能开关：flex布局，对齐文字与开关 */
.memory-switch {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: #666;
}
/* Markdown内容样式 */
.message-content {
  text-align: left;
}
.message-content >>> pre {
  white-space: pre-wrap; /* 关键：让代码自动换行 */
  background-color: #f6f8fa; /* 浅灰色背景，区分代码块 */
  border-radius: 5px;
  overflow-x: auto; /* 当代码过长时显示横向滚动条（可选） */
  font-size: 13px; /* 减小代码字体，节省空间 */
  padding: 1em;
  border-radius: 5px;
  overflow-x: auto;
  margin: 0em;
}
.message-content >>> p{
  display: inline;
  margin: 0em;
}
.message-content >>> ul{
  display: inline-grid;
}
.message-content >>> code {
  font-family: 'Courier New', monospace;
  background-color: #e8f3ff; /* 浅蓝色背景，突出内联代码 */
  padding: 0.2em 0.4em;
  border-radius: 3px;
  font-size: 13px;
}
.message-content >>> h1,
.message-content >>> h2,
.message-content >>> h3,
.message-content >>> h4,
.message-content >>> h5{
  margin: 0em;
  /*margin: 1em 0 0.5em;*/
  font-weight: bold;
  display: inline-grid;
}
.message-content >>> blockquote{
  display: inline !important;
}
.message-content table {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 16px;
}
.message-content th, .message-content td {
  border: 1px solid #dfe2e5;
  padding: 6px 13px;
}
.message-content tr {
  background-color: #fff;
  border-top: 1px solid #c6cbd1;
}
.message-content tr:nth-child(2n) {
  background-color: #f6f8fa;
}
/* 空状态样式 */
.empty-messages {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}
.empty-state {
  text-align: center;
  color: #26B1A1;
  padding: 20px;
}
.eye-icon {
  margin-bottom: 16px;
  color: #26B1A1;
}
.empty-text {
  font-size: 16px;
  max-width: 80%;
  margin: 0 auto;
  line-height: 1.5;
}
.eye-icon svg {
  animation: blink 4s infinite;
}
@keyframes blink {
  0%, 45%, 55%, 100% {
    transform: scaleY(1);
  }
  50% {
    transform: scaleY(0.1);
  }
}
 .left-panel {
   position: relative;
   height: 100%;
   background-color: var(--submenu-background-color,#f9f9f9);
   color: #333;
   display: flex;
   flex-direction: column;
   box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
   overflow: hidden;
   border-right: 1px solid #eee;
 }
.panel-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0px 8px;
  border-bottom: 1px solid #eee;
}
.collapse-btn {
  margin-left:26vh;
  color: #666;
  font-size: 16px;
  background: transparent;
  border: none;
  cursor: pointer;
  transition: all 0.2s ease;
  padding: 4px;
  border-radius: 4px;
}
.collapse-btn:hover {
  color: #1a73e8;
  background-color: rgba(0, 0, 0, 0.03);
}
.new-convo-collapsed {
  width: 36px;
  height: 36px;
  background-color: #1a73e8;
  border: none;
  border-radius: 50%;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}
.new-convo-collapsed:hover {
  background-color: #1557b0;
  transform: scale(1.05);
}
.conversation-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #eee;
}
.conversation-header h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: #444;
}
.new-convo-btn {
  background-color: #26B1A1;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  box-shadow: none;
}
.new-convo-btn:hover {
  background-color: #26B1A1;
}
.new-convo-btn span {
  margin-left: 4px;
}
.conversation-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0;
}
.time-group {
  margin-bottom: 12px;
}
.time-group-title {
  padding: 6px 16px;
  font-size: 11px;
  color: #888;
  letter-spacing: 0.3px;
  font-weight: 500;
}
.conversation-item {
  display: flex;
  align-items: center;
  padding: 10px 16px;
  margin: 0 4px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
}
.conversation-item:hover {
  background-color: rgba(0, 0, 0, 0.03);
}
.conversation-item.active {
  background-color: rgba(26, 115, 232, 0.1);
}
.conversation-content {
  flex: 1;
  min-width: 0;
}
.conversation-title {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 2px;
  color: #333;
}
.conversation-item.active .conversation-title {
  color: #26B1A1;
  font-weight: 500;
}
.conversation-preview {
  font-size: 11px;
  color: #888;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
}
.conversation-item.active .conversation-preview {
  color: #6ea1f1;
}
.timestamp {
  font-size: 10px;
  color: #aaa;
}
.delete-btn {
  width: 22px;
  height: 22px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: #999;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-left: 4px;
}
.conversation-item:hover .delete-btn {
  opacity: 1;
}
.delete-btn:hover {
  color: #ff4d4f;
  background-color: rgba(255, 77, 79, 0.08);
}
/* 问小白风格的滚动条 */
.conversation-list::-webkit-scrollbar {
  width: 4px;
}
.conversation-list::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.01);
}
.conversation-list::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.08);
  border-radius: 2px;
}
.conversation-list::-webkit-scrollbar-thumb:hover {
  background-color: rgba(0, 0, 0, 0.12);
}
/* 加载覆盖层 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(249, 249, 249, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
/* 响应式调整 */
@media (max-width: 768px) {
  .left-panel {
    width: 100%;
    border-right: none;
  }

  .conversation-header {
    padding: 12px 14px;
  }

  .conversation-item {
    padding: 10px 14px;
  }
}
</style>
